﻿using System;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace Atmk.WaterMeter.MIS.TestApp.Common.Utils
{
    /// <summary>
    /// json绑定到TreeView控件
    /// </summary>
    public class JsonTreeViewHelper
    {
        private static readonly ILogger _Logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// 绑定树形控件
        /// </summary>
        /// <param name="treeView"></param>
        /// <param name="strJson"></param>
        public static void BindTreeView(TreeView treeView, string strJson)
        {
            treeView.Nodes.Clear();

            if (IsJOjbect(strJson))
            {
                var jo = (JObject) JsonConvert.DeserializeObject(strJson);

                foreach (var item in jo)
                {
                    TreeNode tree;
                    if (item.Value.GetType() == typeof(JObject))
                    {
                        tree = new TreeNode(item.Key);
                        AddTreeChildNode(ref tree, item.Value.ToString());
                        treeView.Nodes.Add(tree);
                    }
                    else if (item.Value.GetType() == typeof(JArray))
                    {
                        tree = new TreeNode(item.Key);
                        AddTreeChildNode(ref tree, item.Value.ToString());
                        treeView.Nodes.Add(tree);
                    }
                    else
                    {
                        tree = new TreeNode(item.Key + ":" + item.Value);
                        treeView.Nodes.Add(tree);
                    }
                }
            }
            if (IsJArray(strJson))
            {
                var ja = (JArray) JsonConvert.DeserializeObject(strJson);
                var i = 0;
                foreach (var jToken in ja)
                {
                    var item = (JObject) jToken;
                    var tree = new TreeNode("Array [" + (i++) + "]");
                    foreach (var itemOb in item)
                    {
                        TreeNode treeOb;
                        if (itemOb.Value.GetType() == typeof(JObject))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else if (itemOb.Value.GetType() == typeof(JArray))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else
                        {
                            treeOb = new TreeNode(itemOb.Key + ":" + itemOb.Value);
                            tree.Nodes.Add(treeOb);
                        }
                    }
                    treeView.Nodes.Add(tree);
                }
            }
            treeView.ExpandAll();
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="parantNode"></param>
        /// <param name="value"></param>
        public static void AddTreeChildNode(ref TreeNode parantNode, string value)
        {
            if (IsJOjbect(value))
            {
                var jo = (JObject) JsonConvert.DeserializeObject(value);
                try
                {
                    foreach (var item in jo)
                    {
                        TreeNode tree;
                        if (item.Value.GetType() == typeof(JObject))
                        {
                            tree = new TreeNode(item.Key);
                            AddTreeChildNode(ref tree, item.Value.ToString());
                            parantNode.Nodes.Add(tree);
                        }
                        else if (item.Value.GetType() == typeof(JArray))
                        {
                            tree = new TreeNode(item.Key);
                            AddTreeChildNode(ref tree, item.Value.ToString());
                            parantNode.Nodes.Add(tree);
                        }
                        else
                        {
                            tree = new TreeNode(item.Key + ":" + item.Value);
                            parantNode.Nodes.Add(tree);
                        }
                    }
                }
                catch (Exception e)
                {
                    _Logger.Error(e);
                }
            }
            if (!IsJArray(value)) return;
            {
                var ja = (JArray) JsonConvert.DeserializeObject(value);
                var i = 0;
                foreach (var jToken in ja)
                {
                    var tree = new TreeNode("Array [" + (i++) + "]");
                    if (IsJOjbect(jToken.ToString()))
                    {
                        var item = (JObject) jToken;
                        parantNode.Nodes.Add(tree);
                        foreach (var itemOb in item)
                        {
                            TreeNode treeOb;
                            if (itemOb.Value.GetType() == typeof(JObject))
                            {
                                treeOb = new TreeNode(itemOb.Key);
                                AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                                tree.Nodes.Add(treeOb);
                            }
                            else if (itemOb.Value.GetType() == typeof(JArray))
                            {
                                treeOb = new TreeNode(itemOb.Key);
                                AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                                tree.Nodes.Add(treeOb);
                            }
                            else
                            {
                                treeOb = new TreeNode(itemOb.Key + ":" + itemOb.Value);
                                tree.Nodes.Add(treeOb);
                            }
                        }
                    }
                    else
                    {
                        parantNode.Nodes.Add(tree);
                        var treeOb = new TreeNode(jToken.ToString());
                        tree.Nodes.Add(treeOb);
                    }
                }
            }
        }
        
        /// <summary>
        /// 判断是否JOjbect类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static bool IsJOjbect(string value)
        {
            try
            {
                JObject.Parse(value);
                _Logger.Info("是JObject类型");
                return true;
            }
            catch (Exception)
            {
                _Logger.Info("不是JObject类型");
                return false;
            }
        }

        /// <summary>
        /// 判断是否JArray类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static bool IsJArray(string value)
        {
            try
            {
                JArray.Parse(value);
                _Logger.Info("是JArray类型");
                return true;
            }
            catch (Exception)
            {
                _Logger.Info("不是JArray类型");
                return false;
            }
        }
    }
}